package com.ksframework.common.dao;

import java.io.Serializable;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.springframework.util.StringUtils;

import com.ksframework.common.util.StringUtil;

/**
 * 提供一个分页实体,主要用于分页功能. <p>
 * 封装分页和排序查询请求参数, 
 * 封装分页和排序查询的结果. 
 * 
 */
public class Page<T> implements Serializable{

	private static final long serialVersionUID = 5322106943291356028L;

	//顺序
	public static final String ASC = "asc";
	//降序
	public static final String DESC = "desc";

	private int curPage = 1; 			//默认起始页号(当前页,原pageNo)
	private int pageSize = 20;			//每页显示记录数.
	private int pageCount = -1;  		//总页数
	private int rowsCount = -1; 		//总记录数(原totalCount)
	private String orderIndex = null;	//排序字段 (原orderBy)
	private String orderType = DESC;	//默认排序 (原order)
	private boolean autoCount = true; 	//是否统计记录数
	private List<?> result = null; 		//结果

	public Page(){}
	
	public Page(int pageSize) {
		this.pageSize = pageSize;
	}

	public Page(int pageSize, boolean autoCount) {
		this.pageSize = pageSize;
		this.autoCount = autoCount;
	}

	public Page(int pageSize, boolean autoCount,String orderType,String orderIndex) {
		this.pageSize = pageSize;
		this.autoCount = autoCount;
		if (ASC.equalsIgnoreCase(orderType) || DESC.equalsIgnoreCase(orderType)) {
			this.orderType = orderType.toLowerCase();
			this.orderIndex=orderIndex;
		} 
	}
	/***
	 * 
	 * @主要功能：构建分页对象
	 * @param curPage 要显示的页码
	 * @param pageSize 每页显示记录数
	 * @param autoCount 是否统计记录数
	 * @param orderType 排序方式 asc|desc
	 * @param orderIndex 排序字段
	 */
	public Page(int curPage,int pageSize, boolean autoCount,String orderType,String orderIndex){
		this.pageSize = pageSize;
		this.curPage = curPage;
		this.autoCount = autoCount;
		if (StringUtils.hasText(orderIndex) && (ASC.equalsIgnoreCase(orderType) || DESC.equalsIgnoreCase(orderType)) ) {
			this.orderType = orderType.toLowerCase();
			this.orderIndex=orderIndex;
		} 
	}
	
	/**
	 * 根据request获取Page对象
	 * (jGrid组件使用)
	 * @param request
	 * @return
	 */
	public static Page<?>  getInstance(HttpServletRequest request){
		String strPage=request.getParameter("page");     //要显示的页码
		String strRows=request.getParameter("rows");     //每页显示记录数
		String sidx=request.getParameter("sidx");        //排序字段
		String sord=request.getParameter("sord");        //排序规则 e.g. asc/desc
		int no = strPage==null ? 1 : Integer.parseInt(strPage);
		int size = strRows == null ?  20 : Integer.parseInt(strRows);
		if(!StringUtils.hasText(sidx))sidx=null;
		return new Page(no,size, true,sord,sidx);
	}
	
	/***
	 * 
	 * @主要功能：根据request获取Page对象
	 * (分页标签使用)
	 * @author: Snoopy Chen (ctfzh@yahoo.com.cn)
	 * @param request
	 * @return 
	 */
	public static Page<?> initPage(HttpServletRequest request){
		String strCurPage= StringUtil.nullToEmpty(request.getParameter("curPage"));      //要显示的页码
		String strPageSize= StringUtil.nullToEmpty(request.getParameter("pageSize"));  //每页显示记录数
		String strOrderType=request.getParameter("orderType");        //排序规则 e.g. asc/desc
		String strOrderIndex=request.getParameter("orderIndex");    //排序字段

		int _curPage = strCurPage.equals("") ? 1 : Integer.parseInt(strCurPage);
		int _pageSize = strPageSize.equals("") ?  13 : Integer.parseInt(strPageSize);
		if(!StringUtils.hasText(strOrderType)) strOrderType="desc";
		if(!StringUtils.hasText(strOrderIndex)) strOrderIndex=null;

		return new Page(_curPage,_pageSize, true,strOrderType,strOrderIndex);
	}

	/**
	 * 取得倒转的排序方向
	 */
	public String getInverseOrderType() {
		if (orderType.equalsIgnoreCase(DESC))
			return ASC;
		else
			return DESC;
	}

	/**
	 *  获得每页的记录数量,无默认值.
	 * @return
	 */
	public int getPageSize() {
		return pageSize;
	}

	public void setPageSize(int pageSize) {
		this.pageSize = pageSize;
	}

	/**
	 * 是否已设置每页的记录数量.
	 * @return
	 */
	public boolean isPageSizeSetted() {
		return pageSize > -1;
	}


	/**
	 * 根据pageNo和pageSize计算当前页第一条记录在总结果集中的位置,序号从0开始.
	 * @return
	 */
	public int getFirst() {
		if (curPage < 1 || pageSize < 1)
			return -1;
		else
			return ((curPage - 1) * pageSize);
	}

	/**
	 * 是否已设置第一条记录记录在总结果集中的位置.
	 * @return
	 */
	public boolean isFirstSetted() {
		return (curPage > 0 && pageSize > 0);
	}



	/**
	 * 是否已设置排序字段.
	 * @return
	 */
	public boolean isOrderIndexBySetted() {
		return org.apache.commons.lang.StringUtils.isNotBlank(orderIndex);
	}

	/**
	 *  获得排序方向,默认为asc.
	 * @return
	 */
	public String getOrderType() {
		return orderType;
	}

	/**
	 * 设置排序方式向.
	 * @param order 可选值为desc或asc.
	 */
	public void setOrderType(String orderType) {
		if (ASC.equalsIgnoreCase(orderType) || DESC.equalsIgnoreCase(orderType)) {
			this.orderType = orderType.toLowerCase();
		} else
			throw new IllegalArgumentException("orderType should be 'desc' or 'asc'");
	}

	/**
	 * 是否自动获取总页数,默认为false.
	 * 注意本属性仅于query by Criteria时有效,query by HQL时本属性无效.
	 * @return
	 */
	public boolean isAutoCount() {
		return autoCount;
	}

	public void setAutoCount(boolean autoCount) {
		this.autoCount = autoCount;
	}
	
	/**
	 * 页内的数据列表.
	 */
	@SuppressWarnings("unchecked")
	public List getResult() {
		return result;
	}

	@SuppressWarnings("unchecked")
	public void setResult(List result) {
		this.result = result;
	}

	/**
	 * 计算总页数.
	 */
	public int getTotalPages() {
		if (rowsCount == -1)
			return -1;

		int count = rowsCount / pageSize;
		if (rowsCount % pageSize > 0) {
			count++;
		}
		pageCount = count;
		return count;
	}

	/**
	 * 是否还有下一页.
	 */
	public boolean isHasNext() {
		return (curPage + 1 <= getTotalPages());
	}

	/**
	 * 返回下页的页号,序号从1开始.
	 */
	public int getNextPage() {
		if (isHasNext())
			return curPage + 1;
		else
			return curPage;
	}

	/**
	 * 是否还有上一页. 
	 */
	public boolean isHasPre() {
		return (curPage - 1 >= 1);
	}

	/**
	 * 返回上页的页号,序号从1开始.
	 */
	public int getPrePage() {
		if (isHasPre())
			return curPage - 1;
		else
			return curPage;
	}

	public int getCurPage() {
		return curPage;
	}

	public void setCurPage(int curPage) {
		this.curPage = curPage;
	}

	public int getPageCount() {
		return pageCount;
	}

	public void setPageCount(int pageCount) {
		this.pageCount = pageCount;
	}

	public int getRowsCount() {
		return rowsCount;
	}

	public void setRowsCount(int rowsCount) {
		this.rowsCount = rowsCount;
	}

	public String getOrderIndex() {
		return orderIndex;
	}

	public void setOrderIndex(String orderIndex) {
		this.orderIndex = orderIndex;
	}

}
